#include <string.h>
#include <stdlib.h>
#include "stdio.h"
#include "pthread.h"
#include "securec.h"
#include "los_interrupt.h"
#include "lfs.h"
#include "w25qxx.h"

/* Logic partition on flash devices, if open at the same time, needed modify by user */

extern HalLogicPartition g_halPartitions[2];

INT32 lfs_erase(HalPartition pdrv, UINT32 offSet, UINT32 size)
{
    UINT32 startAddr = offSet;
    UINT32 partitionEnd;
	// 获取分区结束地址
    partitionEnd = g_halPartitions[pdrv].partitionStartAddr + g_halPartitions[pdrv].partitionLength;
    // 判断起始地址是否超出范围
	if (startAddr >= partitionEnd) {
        printf("sd over erase, 0x%x, 0x%x\r\n", startAddr, partitionEnd);
        printf("sd over write\r\n");
        return -1;
    }
	// 判断擦除长度是否超出范围
    if ((startAddr + size) > partitionEnd) {
        size = partitionEnd - startAddr;
        printf("sd over write, new len is %d\r\n", size);
    }
	// 调用硬件擦除函数
    W25QXX_Erase_Sector(offSet/512);
    return 0;
}

INT32 lfs_write(HalPartition pdrv, UINT32 *offSet, const VOID *buf, UINT32 bufLen)
{
    UINT32 startAddr = *offSet;
    UINT32 partitionEnd;
	// 获取分区结束地址
    partitionEnd = g_halPartitions[pdrv].partitionStartAddr + g_halPartitions[pdrv].partitionLength;
    // 判断起始地址是否超出范围
	if (startAddr >= partitionEnd) {
        printf("flash over write, 0x%x, 0x%x\r\n", startAddr, partitionEnd);
        return -1;
    }
	// 判断写入长度是否超出范围
    if ((startAddr + bufLen) > partitionEnd) {
        bufLen = partitionEnd - startAddr;
        printf("flash over write, new len is %d\r\n", bufLen);
    }
	// 调用硬件写入函数
    UINT32 intSave = LOS_IntLock();
    W25QXX_Write(buf, *offSet, bufLen);
    LOS_IntRestore(intSave);

    return 0;
}

INT32 lfs_read(HalPartition pdrv, UINT32 *offSet, VOID *buf, UINT32 bufLen)
{
    UINT32 startAddr = *offSet;
    UINT32 partitionEnd;
	// 获取分区结束地址
    partitionEnd = g_halPartitions[pdrv].partitionStartAddr + g_halPartitions[pdrv].partitionLength;
    // 判断起始地址是否超出范围
	if (startAddr >= partitionEnd) {
        printf("flash over read, 0x%x, 0x%x\r\n", startAddr, partitionEnd);
        return -1;
    }
	// 判断读取长度是否超出范围
    if ((startAddr + bufLen) > partitionEnd) {
        bufLen = partitionEnd - startAddr;
        printf("flash over read, new len is %d\r\n", bufLen);
    }
	// 调用硬件读取函数
    UINT32 intSave = LOS_IntLock();
    W25QXX_Read(buf, *offSet, bufLen);
    LOS_IntRestore(intSave);
    return 0;
}
